using Microsoft.Win32;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing.Printing;
using System.IO;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Threading;

namespace ImageToWordWPF
{
    public partial class MainWindow : Window
    {
        private List<string> selectedImagePaths = new List<string>();
        private WordDocumentGenerator wordGenerator;
        private DispatcherTimer messageTimer;
        private string pendingDocumentPath; // 用于存储待打开的文档路径
        private bool isProcessing = false; // 标记是否正在处理中
        private CancellationTokenSource cancellationTokenSource;

        public MainWindow()
        {
            InitializeComponent();
            wordGenerator = new WordDocumentGenerator();

            // 初始化消息自动隐藏定时器
            messageTimer = new DispatcherTimer();
            messageTimer.Interval = TimeSpan.FromSeconds(5);
            messageTimer.Tick += (s, e) => HideMessage();
        }

        private void BtnUploadImages_Click(object sender, RoutedEventArgs e)
        {
            if (isProcessing) return;

            OpenFileDialog openFileDialog = new OpenFileDialog
            {
                Title = "选择图片文件",
                Filter = "图片文件|*.jpg;*.jpeg;*.png;*.bmp;*.gif;*.tiff|所有文件|*.*",
                Multiselect = true
            };

            if (openFileDialog.ShowDialog() == true)
            {
                SetProcessingState(true, "正在加载图片...");

                // 使用 Task.Factory.StartNew 替代 Task.Run
                var task = Task.Factory.StartNew(() =>
                {
                    List<string> validPaths = new List<string>();
                    foreach (string path in openFileDialog.FileNames)
                    {
                        try
                        {
                            // 验证是否为有效图片文件
                            using (var img = System.Drawing.Image.FromFile(path))
                            {
                                validPaths.Add(path);
                            }
                        }
                        catch
                        {
                            // 无效图片文件，跳过
                            System.Diagnostics.Debug.WriteLine(string.Format("跳过无效图片: {0}", path));
                        }
                    }
                    return validPaths;
                }, TaskCreationOptions.LongRunning);

                task.ContinueWith(t =>
                {
                    try
                    {
                        if (t.Exception == null)
                        {
                            var validImages = t.Result;

                            // 在UI线程更新界面
                            Dispatcher.BeginInvoke(new Action(() =>
                            {
                                selectedImagePaths.AddRange(validImages);
                                UpdateUI();

                                // 同步生成预览（简化版本）
                                GeneratePreview();

                                ShowMessage(string.Format("成功添加 {0} 张有效图片", validImages.Count), MessageType.Success);

                                if (validImages.Count < openFileDialog.FileNames.Length)
                                {
                                    int invalidCount = openFileDialog.FileNames.Length - validImages.Count;
                                    ShowMessage(string.Format("已跳过 {0} 个无效文件", invalidCount), MessageType.Warning);
                                }
                            }));
                        }
                        else
                        {
                            Dispatcher.BeginInvoke(new Action(() =>
                            {
                                ShowMessage(string.Format("加载图片时发生错误：{0}", t.Exception.InnerException.Message), MessageType.Error);
                            }));
                        }
                    }
                    finally
                    {
                        Dispatcher.BeginInvoke(new Action(() =>
                        {
                            SetProcessingState(false);
                        }));
                    }
                }, TaskScheduler.Default);
            }
        }

        private void BtnExportWord_Click(object sender, RoutedEventArgs e)
        {
            if (isProcessing || selectedImagePaths.Count == 0)
            {
                ShowMessage("请先选择图片！", MessageType.Warning);
                return;
            }

            SaveFileDialog saveFileDialog = new SaveFileDialog
            {
                Title = "保存Word文档",
                Filter = "Word文档|*.docx",
                DefaultExt = ".docx"
            };

            if (saveFileDialog.ShowDialog() == true)
            {
                SetProcessingState(true, "正在生成Word文档...");
                ShowMessage("正在生成Word文档，请稍候...", MessageType.Info);

                // 创建取消令牌
                cancellationTokenSource = new CancellationTokenSource();

                // 订阅进度事件
                wordGenerator.ProgressReport += OnWordGeneratorProgress;

                bool showBorders = chkShowBorders.IsChecked ?? true;
                double cellMargin = 5;
                double.TryParse(txtCellMargin.Text, out cellMargin);

                // 使用 Task.Factory.StartNew 替代异步方法
                var task = wordGenerator.CreateWordDocumentAsync(
                    selectedImagePaths,
                    saveFileDialog.FileName,
                    showBorders,
                    cellMargin,
                    cancellationTokenSource.Token);

                task.ContinueWith(t =>
                {
                    Dispatcher.BeginInvoke(new Action(() =>
                    {
                        try
                        {
                            if (t.Exception == null && !t.IsCanceled)
                            {
                                statusText.Text = "Word文档导出成功！";
                                pendingDocumentPath = saveFileDialog.FileName;
                                ShowMessage("Word文档已成功导出！是否立即打开文档？", MessageType.Question, true);
                            }
                            else if (t.IsCanceled)
                            {
                                statusText.Text = "导出已取消";
                                ShowMessage("Word文档导出已取消", MessageType.Warning);
                            }
                            else
                            {
                                var ex = t.Exception.InnerException ?? t.Exception;
                                statusText.Text = "导出失败";
                                ShowMessage(string.Format("导出Word文档时发生错误：{0}", ex.Message), MessageType.Error);
                            }
                        }
                        finally
                        {
                            // 取消订阅进度事件
                            wordGenerator.ProgressReport -= OnWordGeneratorProgress;
                            if (cancellationTokenSource != null)
                            {
                                cancellationTokenSource.Dispose();
                                cancellationTokenSource = null;
                            }
                            SetProcessingState(false);
                        }
                    }));
                }, TaskScheduler.Default);
            }
        }

        private void BtnPrint_Click(object sender, RoutedEventArgs e)
        {
            if (isProcessing || selectedImagePaths.Count == 0)
            {
                ShowMessage("请先选择图片！", MessageType.Warning);
                return;
            }

            try
            {
                PrintDialog printDialog = new PrintDialog();
                if (printDialog.ShowDialog() == true)
                {
                    SetProcessingState(true, "正在准备打印文档...");
                    ShowMessage("正在准备打印文档，请稍候...", MessageType.Info);

                    // 创建取消令牌
                    cancellationTokenSource = new CancellationTokenSource();

                    // 订阅进度事件
                    wordGenerator.ProgressReport += OnWordGeneratorProgress;

                    // 创建临时Word文档用于打印
                    string tempPath = Path.GetTempFileName() + ".docx";

                    bool showBorders = chkShowBorders.IsChecked ?? true;
                    double cellMargin = 5;
                    double.TryParse(txtCellMargin.Text, out cellMargin);

                    // 生成文档然后打印
                    var createTask = wordGenerator.CreateWordDocumentAsync(
                        selectedImagePaths,
                        tempPath,
                        showBorders,
                        cellMargin,
                        cancellationTokenSource.Token);

                    createTask.ContinueWith(t1 =>
                    {
                        if (t1.Exception == null && !t1.IsCanceled)
                        {
                            // 继续打印任务
                            var printTask = wordGenerator.PrintWordDocumentAsync(tempPath, cancellationTokenSource.Token);

                            printTask.ContinueWith(t2 =>
                            {
                                Dispatcher.BeginInvoke(new Action(() =>
                                {
                                    try
                                    {
                                        if (t2.Exception == null && !t2.IsCanceled)
                                        {
                                            statusText.Text = "文档已发送到打印机";
                                            ShowMessage("文档已发送到打印机", MessageType.Success);
                                        }
                                        else if (t2.IsCanceled)
                                        {
                                            statusText.Text = "打印已取消";
                                            ShowMessage("打印操作已取消", MessageType.Warning);
                                        }
                                        else
                                        {
                                            var ex = t2.Exception.InnerException ?? t2.Exception;
                                            ShowMessage(string.Format("打印时发生错误：{0}", ex.Message), MessageType.Error);
                                        }
                                    }
                                    finally
                                    {
                                        // 取消订阅进度事件
                                        wordGenerator.ProgressReport -= OnWordGeneratorProgress;
                                        if (cancellationTokenSource != null)
                                        {
                                            cancellationTokenSource.Dispose();
                                            cancellationTokenSource = null;
                                        }
                                        SetProcessingState(false);
                                    }
                                }));
                            }, TaskScheduler.Default);
                        }
                        else
                        {
                            Dispatcher.BeginInvoke(new Action(() =>
                            {
                                if (t1.IsCanceled)
                                {
                                    statusText.Text = "打印已取消";
                                    ShowMessage("打印操作已取消", MessageType.Warning);
                                }
                                else
                                {
                                    var ex = t1.Exception.InnerException ?? t1.Exception;
                                    ShowMessage(string.Format("准备打印时发生错误：{0}", ex.Message), MessageType.Error);
                                }

                                // 取消订阅进度事件
                                wordGenerator.ProgressReport -= OnWordGeneratorProgress;
                                if (cancellationTokenSource != null)
                                {
                                    cancellationTokenSource.Dispose();
                                    cancellationTokenSource = null;
                                }
                                SetProcessingState(false);
                            }));
                        }
                    }, TaskScheduler.Default);
                }
            }
            catch (Exception ex)
            {
                ShowMessage(string.Format("打印时发生错误：{0}", ex.Message), MessageType.Error);
                SetProcessingState(false);
            }
        }

        private void BtnClearImages_Click(object sender, RoutedEventArgs e)
        {
            if (isProcessing) return;

            selectedImagePaths.Clear();
            UpdateUI();
            ClearPreview();
            ShowMessage("已清空所有图片", MessageType.Info);
        }

        private void UpdateUI()
        {
            lblSelectedCount.Content = string.Format("已选择: {0} 张图片", selectedImagePaths.Count);
            btnExportWord.IsEnabled = selectedImagePaths.Count > 0 && !isProcessing;
            btnPrint.IsEnabled = selectedImagePaths.Count > 0 && !isProcessing;
            btnClearImages.IsEnabled = selectedImagePaths.Count > 0 && !isProcessing;
            btnUploadImages.IsEnabled = !isProcessing;

            statusText.Text = selectedImagePaths.Count > 0 ?
                string.Format("已加载 {0} 张图片", selectedImagePaths.Count) : "就绪";
        }

        /// <summary>
        /// 设置处理状态，控制UI元素的启用/禁用
        /// </summary>
        /// <param name="processing">是否正在处理</param>
        /// <param name="statusMessage">状态消息</param>
        private void SetProcessingState(bool processing, string statusMessage)
        {
            SetProcessingState(processing, statusMessage, true);
        }

        private void SetProcessingState(bool processing)
        {
            SetProcessingState(processing, null, false);
        }

        private void SetProcessingState(bool processing, string statusMessage, bool hasStatusMessage)
        {
            isProcessing = processing;

            // 更新UI控件状态
            UpdateUI();

            // 显示加载指示器
            if (processing)
            {
                this.Cursor = System.Windows.Input.Cursors.Wait;
                if (hasStatusMessage && !string.IsNullOrEmpty(statusMessage))
                {
                    statusText.Text = statusMessage;
                }
            }
            else
            {
                this.Cursor = System.Windows.Input.Cursors.Arrow;
            }
        }

        private void GeneratePreview()
        {
            try
            {
                previewPanel.Children.Clear();

                if (selectedImagePaths.Count == 0)
                {
                    TextBlock emptyText = new TextBlock
                    {
                        Text = "请选择图片进行预览",
                        HorizontalAlignment = HorizontalAlignment.Center,
                        VerticalAlignment = VerticalAlignment.Center,
                        FontSize = 14,
                        Foreground = Brushes.Gray,
                        Margin = new Thickness(20)
                    };
                    previewPanel.Children.Add(emptyText);
                    return;
                }

                bool showBorders = chkShowBorders.IsChecked ?? true;
                double cellMargin = 5;
                double.TryParse(txtCellMargin.Text, out cellMargin);

                // 简化的同步预览生成
                var imageGroups = selectedImagePaths
                    .Select((path, index) => new { Path = path, Index = index })
                    .GroupBy(x => x.Index / 9)
                    .Select(g => g.Select(x => x.Path).ToList())
                    .ToList();

                foreach (var group in imageGroups)
                {
                    CreatePreviewPage(group, showBorders, cellMargin);
                }

                statusText.Text = string.Format("预览已生成，共 {0} 页", imageGroups.Count);
            }
            catch (Exception ex)
            {
                ShowMessage(string.Format("生成预览时发生错误：{0}", ex.Message), MessageType.Error);
            }
        }

        private void CreatePreviewPage(List<string> imagePaths, bool showBorders, double cellMargin)
        {
            // 页面容器
            Border pageContainer = new Border
            {
                Background = Brushes.White,
                BorderBrush = Brushes.LightGray,
                BorderThickness = new Thickness(1),
                Margin = new Thickness(10),
                Padding = new Thickness(20)
            };

            // 创建3x3网格
            Grid grid = new Grid
            {
                Width = 600,
                Height = 600
            };

            // 定义行和列
            for (int i = 0; i < 3; i++)
            {
                grid.RowDefinitions.Add(new RowDefinition { Height = new GridLength(1, GridUnitType.Star) });
                grid.ColumnDefinitions.Add(new ColumnDefinition { Width = new GridLength(1, GridUnitType.Star) });
            }

            // 同步加载图片到网格
            for (int i = 0; i < imagePaths.Count && i < 9; i++)
            {
                int row = i / 3;
                int col = i % 3;
                string imagePath = imagePaths[i];

                Border cellBorder = new Border
                {
                    BorderThickness = showBorders ? new Thickness(1) : new Thickness(0),
                    BorderBrush = Brushes.Black,
                    Margin = new Thickness(cellMargin)
                };

                try
                {
                    BitmapImage bitmap = new BitmapImage();
                    bitmap.BeginInit();
                    bitmap.UriSource = new Uri(imagePath);
                    bitmap.CacheOption = BitmapCacheOption.OnLoad;
                    bitmap.EndInit();

                    Image image = new Image
                    {
                        Source = bitmap,
                        Stretch = Stretch.Uniform,
                        StretchDirection = StretchDirection.Both
                    };

                    cellBorder.Child = image;
                }
                catch
                {
                    TextBlock errorText = new TextBlock
                    {
                        Text = "加载失败",
                        HorizontalAlignment = HorizontalAlignment.Center,
                        VerticalAlignment = VerticalAlignment.Center,
                        Foreground = Brushes.Red
                    };
                    cellBorder.Child = errorText;
                }

                Grid.SetRow(cellBorder, row);
                Grid.SetColumn(cellBorder, col);
                grid.Children.Add(cellBorder);
            }

            pageContainer.Child = grid;
            previewPanel.Children.Add(pageContainer);
        }

        private void ClearPreview()
        {
            previewPanel.Children.Clear();
            TextBlock emptyText = new TextBlock
            {
                Text = "请选择图片进行预览",
                HorizontalAlignment = HorizontalAlignment.Center,
                VerticalAlignment = VerticalAlignment.Center,
                FontSize = 14,
                Foreground = Brushes.Gray,
                Margin = new Thickness(20)
            };
            previewPanel.Children.Add(emptyText);
        }

        // 当设置改变时重新生成预览
        private void ChkShowBorders_CheckedChanged(object sender, RoutedEventArgs e)
        {
            if (selectedImagePaths.Count > 0 && !isProcessing)
            {
                SetProcessingState(true, "更新预览中...");
                try
                {
                    GeneratePreview();
                }
                finally
                {
                    SetProcessingState(false);
                }
            }
        }

        private void TxtCellMargin_TextChanged(object sender, TextChangedEventArgs e)
        {
            if (selectedImagePaths.Count > 0 && !isProcessing)
            {
                SetProcessingState(true, "更新预览中...");

                // 使用 DispatcherTimer 替代 Task.Delay
                DispatcherTimer delayTimer = new DispatcherTimer();
                delayTimer.Interval = TimeSpan.FromMilliseconds(300);
                delayTimer.Tick += (s, args) =>
                {
                    delayTimer.Stop();
                    try
                    {
                        if (isProcessing) // 确认还在处理状态
                        {
                            GeneratePreview();
                        }
                    }
                    finally
                    {
                        SetProcessingState(false);
                    }
                };
                delayTimer.Start();
            }
        }

        #region 消息控件相关方法

        /// <summary>
        /// 消息类型枚举
        /// </summary>
        public enum MessageType
        {
            Info,       // 信息
            Success,    // 成功
            Warning,    // 警告
            Error,      // 错误
            Question    // 询问
        }

        /// <summary>
        /// 显示消息
        /// </summary>
        /// <param name="message">消息内容</param>
        /// <param name="type">消息类型</param>
        /// <param name="needConfirm">是否需要确认</param>
        private void ShowMessage(string message, MessageType type, bool needConfirm)
        {
            // 停止之前的定时器
            messageTimer.Stop();

            // 设置消息文本
            messageText.Text = message;

            // 根据消息类型设置图标和颜色
            switch (type)
            {
                case MessageType.Info:
                    messageIcon.Text = "ℹ";
                    messageIcon.Foreground = Brushes.DodgerBlue;
                    messagePanel.Background = new SolidColorBrush(Color.FromRgb(217, 237, 247));
                    messagePanel.BorderBrush = new SolidColorBrush(Color.FromRgb(126, 182, 193));
                    break;
                case MessageType.Success:
                    messageIcon.Text = "✓";
                    messageIcon.Foreground = Brushes.Green;
                    messagePanel.Background = new SolidColorBrush(Color.FromRgb(223, 240, 216));
                    messagePanel.BorderBrush = new SolidColorBrush(Color.FromRgb(133, 153, 0));
                    break;
                case MessageType.Warning:
                    messageIcon.Text = "⚠";
                    messageIcon.Foreground = Brushes.Orange;
                    messagePanel.Background = new SolidColorBrush(Color.FromRgb(252, 248, 227));
                    messagePanel.BorderBrush = new SolidColorBrush(Color.FromRgb(179, 146, 24));
                    break;
                case MessageType.Error:
                    messageIcon.Text = "✗";
                    messageIcon.Foreground = Brushes.Red;
                    messagePanel.Background = new SolidColorBrush(Color.FromRgb(248, 215, 218));
                    messagePanel.BorderBrush = new SolidColorBrush(Color.FromRgb(220, 53, 69));
                    break;
                case MessageType.Question:
                    messageIcon.Text = "?";
                    messageIcon.Foreground = Brushes.Purple;
                    messagePanel.Background = new SolidColorBrush(Color.FromRgb(233, 236, 239));
                    messagePanel.BorderBrush = new SolidColorBrush(Color.FromRgb(108, 117, 125));
                    break;
            }

            // 设置确认按钮可见性
            btnConfirm.Visibility = needConfirm ? Visibility.Visible : Visibility.Collapsed;

            // 显示消息面板
            messagePanel.Visibility = Visibility.Visible;

            // 如果不需要确认，5秒后自动隐藏
            if (!needConfirm)
            {
                messageTimer.Start();
            }
        }

        private void ShowMessage(string message, MessageType type)
        {
            ShowMessage(message, type, false);
        }

        /// <summary>
        /// 隐藏消息
        /// </summary>
        private void HideMessage()
        {
            messageTimer.Stop();
            messagePanel.Visibility = Visibility.Collapsed;
            btnConfirm.Visibility = Visibility.Collapsed;
            pendingDocumentPath = null;
        }

        /// <summary>
        /// 关闭消息按钮点击事件
        /// </summary>
        private void BtnCloseMessage_Click(object sender, RoutedEventArgs e)
        {
            HideMessage();
        }

        /// <summary>
        /// 确认按钮点击事件
        /// </summary>
        private void BtnConfirm_Click(object sender, RoutedEventArgs e)
        {
            // 处理文档打开确认
            if (!string.IsNullOrEmpty(pendingDocumentPath))
            {
                SetProcessingState(true, "正在打开文档...");

                // 在后台线程尝试打开文档
                Task.Factory.StartNew(() =>
                {
                    try
                    {
                        // 使用系统默认程序打开文档
                        System.Diagnostics.Process.Start(new System.Diagnostics.ProcessStartInfo
                        {
                            FileName = pendingDocumentPath,
                            UseShellExecute = true
                        });

                        Dispatcher.BeginInvoke(new Action(() =>
                        {
                            statusText.Text = "文档已打开";
                            ShowMessage("文档已成功打开", MessageType.Success);
                        }));
                    }
                    catch (Exception ex)
                    {
                        Dispatcher.BeginInvoke(new Action(() =>
                        {
                            ShowMessage(string.Format("无法打开文档：{0}\n文档已保存至：{1}", ex.Message, pendingDocumentPath), MessageType.Error);
                            statusText.Text = "文档已保存，但打开失败";
                        }));
                    }
                    finally
                    {
                        Dispatcher.BeginInvoke(new Action(() =>
                        {
                            SetProcessingState(false);
                        }));
                    }
                }, TaskCreationOptions.LongRunning);
            }
            else
            {
                HideMessage();
            }
        }

        /// <summary>
        /// Word生成器进度回调
        /// </summary>
        private void OnWordGeneratorProgress(int current, int total, string message)
        {
            // 确保在UI线程中更新界面
            Dispatcher.BeginInvoke(new Action(() =>
            {
                if (total > 0)
                {
                    double percentage = (double)current / total * 100;
                    statusText.Text = string.Format("{0} ({1:F1}%)", message, percentage);
                }
                else
                {
                    statusText.Text = message;
                }
            }));
        }

        // 添加取消操作的方法（可选）
        private void BtnCancelOperation_Click(object sender, RoutedEventArgs e)
        {
            if (cancellationTokenSource != null && !cancellationTokenSource.Token.IsCancellationRequested)
            {
                cancellationTokenSource.Cancel();
                ShowMessage("正在取消操作...", MessageType.Info);
            }
        }

        #endregion

        // 窗体控制事件处理方法
        private void TitleBar_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
        {
            if (e.ClickCount == 2)
            {
                // 双击标题栏切换最大化状态
                WindowState = WindowState == WindowState.Maximized ? WindowState.Normal : WindowState.Maximized;
                UpdateMaximizeButtonIcon();
            }
            else
            {
                // 拖动窗体
                this.DragMove();
            }
        }

        private void MinimizeButton_Click(object sender, RoutedEventArgs e)
        {
            WindowState = WindowState.Minimized;
        }

        private void MaximizeButton_Click(object sender, RoutedEventArgs e)
        {
            WindowState = WindowState == WindowState.Maximized ? WindowState.Normal : WindowState.Maximized;
            UpdateMaximizeButtonIcon();
        }

        private void CloseButton_Click(object sender, RoutedEventArgs e)
        {
            this.Close();
        }

        private void UpdateMaximizeButtonIcon()
        {
            MaximizeButton.Content = WindowState == WindowState.Maximized ? "⧉" : "□";
        }
    }
}
